/* 
 *	Copyright 2014  Yanqing Wu
 *		email: yqwu_yqwu@126.com
 *
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 *
*/

#include "stdafx.h"
#include "StdCtrlSkin.h"

#include "StdCtrlSkinTool_Utils.h"

CStdCtrlSkin::CStdCtrlSkin(void)
{
}


CStdCtrlSkin::~CStdCtrlSkin(void)
{
	for(auto i : m_wnd_list)
		delete i.second;
}

void CStdCtrlSkin::Reset(void)
{
	for(auto i : m_wnd_list)
		delete i.second;
	m_wnd_list.clear();
}

bool CStdCtrlSkin::LoadConfigFile(CString filename)
{
	Reset();
	CComPtr<IXMLDOMDocument> spDoc;
	VARIANT_BOOL vb;
	auto hr = spDoc.CoCreateInstance(__uuidof(DOMDocument));
	if ( FAILED(hr) )
		return false;
	spDoc->load(CComVariant(filename), &vb);
	if ( vb==FALSE )
		return false;
	CComPtr<IXMLDOMElement> spRoot;
	spDoc->get_documentElement(&spRoot);
	auto attribPairs = StdCtrlSkinTool_XmlGetAttribPairs(spRoot);
	auto pEnum = StdCtrlSkinTool_GetEnum();
	CStdCtrlSkin_EnumAttrib attrib;
	for(auto i : attribPairs)
	{
		auto name = i.first;
		auto value = i.second;
		auto correct = pEnum->Parse(attrib, name);
		if ( !correct )
		{
			SetCustomAttrib(name, value);
			continue;
		}
		switch(attrib)
		{
		case CStdCtrlSkin_EnumAttrib::VERSION:
			m_version = value;
			break;
		default:
			SetCustomAttrib(name, value);
			break;
		}
	}
	CComPtr<IXMLDOMNodeList> spChildren;
	spRoot->get_childNodes(&spChildren);
	long length;
	spChildren->get_length(&length);
	UINT count = 0;
	CStdCtrlSkinWnd* pWnd;
	for(long i=0; i!=length; ++i)
	{
		CComPtr<IXMLDOMNode> spChild;
		spChildren->get_item(i, &spChild);
		auto name = StdCtrlSkinTool_XmlGetNodeName(spChild);
		CStdCtrlSkin_EnumSubNode type;
		auto correct = pEnum->Parse(type, name);
		if ( !correct )
			continue;
		switch(type)
		{
		case CStdCtrlSkin_EnumSubNode::WINDOW:
			pWnd = new CStdCtrlSkinWnd(spChild, this);
			m_wnd_list[pWnd->window_name] = pWnd;
			break;
		default:
			break;
		}
	}
	try {
		CFile cFile(filename, CFile::modeRead);
		m_filename = cFile.GetFileName();
		auto path = cFile.GetFilePath();
		auto length = m_filename.GetLength();
		m_filepath = path.Left(path.GetLength() - length);
	}
	catch (CFileException* pEx)
	{
	}
	return true;
}

bool CStdCtrlSkin::SetWndRect(CString wndName, CRect rect)
{
	if ( m_wnd_list.find(wndName) == m_wnd_list.end() )
		return false;
	auto pWnd = m_wnd_list[wndName];
	pWnd->SetRect(rect);
	return true;
}

bool CStdCtrlSkin::LogControl(CString wndName, CString ctrlName, CWnd* pCtrl)
{
	if ( m_wnd_list.find(wndName) == m_wnd_list.end() )
		return false;
	m_wnd_list[wndName]->LogControl(ctrlName, pCtrl);
	return true;
}

bool CStdCtrlSkin::UnlogControl(CWnd* pCtrl)
{
	for(auto i : m_wnd_list)
		i.second->UnlogControl(pCtrl);
	return true;
}

bool CStdCtrlSkin::DoLayout(CString wndName, CRect rect)
{
	if ( m_wnd_list.find(wndName) == m_wnd_list.end() )
		return false;
	m_wnd_list[wndName]->DoLayOut(rect);
	return true;
}

HBITMAP CStdCtrlSkin::GetBitmap(CString wndName, CSize size, HDC hDC)
{
	if ( m_wnd_list.find(wndName) == m_wnd_list.end() )
		return NULL;
	return m_wnd_list[wndName]->GetBitmap(size, hDC);
}

void CStdCtrlSkin::SetWndBackColor(CString wndName, COLORREF color)
{
	if ( m_wnd_list.find(wndName) == m_wnd_list.end() )
		return;
	m_wnd_list[wndName]->SetBackColor(color);
}

#ifdef __DUMPTEST
void CStdCtrlSkin::Dump(CString pathname, CStdCtrlSkin_EnumDump type)
{
	std::ofstream fio;
	fio.open(pathname, std::ios_base::out);
	for(auto i : m_wnd_list)
		i.second->Dump(fio, type);
	fio.close();
}
#endif